import 'dart:async';
import 'dart:io';

import 'package:fbroadcast/fbroadcast.dart';
import 'package:fixnum/fixnum.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:xvideos/hj_page/zaixiankefu/chat_widget/chat_core/network/connection/msg_manager.dart';
import 'package:xvideos/hj_page/zaixiankefu/chat_widget/chat_page/List_component/chat_pic.dart';
import 'package:xvideos/hj_page/zaixiankefu/chat_widget/chat_page/utils/util.dart';
import 'package:xvideos/hj_page/zaixiankefu/chat_widget/chat_page/utils/visible.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';

import '../../chat_core/network/connection/connect_util.dart';
import '../../chat_core/network/connection/download_manager.dart';
import '../../chat_core/network/connection/notification_center.dart';
import '../../chat_core/network/connection/socket_manager.dart';
import '../../chat_core/network/utils/file_manager.dart';
import '../../chat_core/pkt/pb.pb.dart';
import '../../chat_core/time_tool/date_util.dart';
import '../../chat_model/chatFaqModel.dart';
import '../../chat_model/chat_faq_model.dart';
import '../ChatPage.dart';
import '../key_board_component/KeyBoardComponentPage.dart';
import '../utils/tool.dart';
import 'back_text.dart';
import 'chat_anwser.dart';
import 'chat_more_question.dart';
import 'chat_question.dart';
import 'chat_relink.dart';
import 'chat_sys.dart';
import 'chat_text.dart';

class ListComponentPage extends StatefulWidget {
  GlobalKey<KeyBoardComponentPageState> keyBoardComponentPageState;

  ListComponentPage({
    Key? key,
    required this.keyBoardComponentPageState,
    required this.list,
    this.playerInfo,
    this.forcePlayerInfo,
    this.chatFields,
    this.servicerInfoFields,
    this.timeServicerInfoFields,
    this.isScrollToBottom,
    this.images,
    this.currentSessionId,
    this.customerAvatar,
    this.customername,
    this.userAvatar,
    this.username,
    this.isNeedKeyboard,
    this.loadingState,
    this.questBean,
    this.faqModel,
    this.questType,
    this.reverse,
    this.currentQuestion,
    this.chatAnwserModel,
    required this.sendMsgStatus,
    required this.sendTimer,
  }) : super(key: key);

  // 用户信息
  PlayerInfo? playerInfo;
  //前端传过来的值用新的PlayerInfo接收
  PlayerInfo? forcePlayerInfo;

  // 客服返回信息
  ChatFields? chatFields;
  // 客服基本信息
  ServicerInfoFields? servicerInfoFields;
  //展示faq数据的时候 需要配置顶部时间展示 定义为ServicerInfoFields类型
  ServicerInfoFields? timeServicerInfoFields;
  // 数据列表
  List<dynamic> list = [];

  //是否需要滑动到底部
  bool? isScrollToBottom;

  // 上传文件状态集合
  Map<String, File>? images;

  //记录当前的session_id 用来拉去历史记录
  String? currentSessionId;

  //客服头像
  String? customerAvatar;
  //客服名字
  String? customername;
  //用户头像
  String? userAvatar;
  //用户名字
  String? username;
  //判断当前是否连接websocket 通过判断键盘是否隐藏来决定
  bool? isNeedKeyboard;

  // 本地图片加载遮罩层
  Map<String, bool>? loadingState;

//faq问题集
  QuestBean? questBean;
  //记录faq数据
  FaqModel? faqModel;

  int? questType;

  //LIstView是否倒置 默认是false
  bool? reverse;

  //记录当前选择的问题分类
  String? currentQuestion;
  //记录当前分类问题下的答案
  ChatAnwserModel? chatAnwserModel;

  // bool isConnect;

  ObtainRefreshController controller = ObtainRefreshController();

  // 正在连接...
  String pointText = "正在连接服务器...";

  // socket 状态
  var socketType = MsgUtils.state();

  // 发送消息状态
  Map sendMsgStatus = {};
  List sendTimer = [];
  // 排队时间
  int waitCount = 0;

  @override
  State<ListComponentPage> createState() => ListComponentPageState();
}

class ObtainRefreshController extends RefreshController {
  factory ObtainRefreshController() => _getInstance();

  static ObtainRefreshController? _instance;

  ObtainRefreshController._internal() {
    // 初始化
  }
  static ObtainRefreshController _getInstance() {
    _instance ??= ObtainRefreshController._internal();
    return _instance!;
  }
}

class ListComponentPageState extends State<ListComponentPage> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return NotificationListener<ScrollNotification>(
      onNotification: (ScrollNotification notification) {
        if (notification is ScrollEndNotification) {
          _onSendReadStatus(indexList);
          indexList.clear();
        }
        return false;
      },
      child: Flexible(
        child: SmartRefresher(
          controller: widget.controller,
          footer: CustomFooter(builder: (BuildContext context, LoadStatus? mode) {
            return Container();
          }),
          enablePullDown: widget.reverse == false ? true : false,
          enablePullUp: widget.reverse == false ? false : true,
          onLoading: () {
            _onRefresh();
          },
          onRefresh: () {
            _onRefresh();
          },
          child: Column(
            children: <Widget>[
              Visibility(
                  visible: widget.socketType == SocketStateEnum.CONNECTED,
                  child: Expanded(
                      child: ListView.custom(
                    reverse: widget.reverse ?? false,
                    childrenDelegate: MySliverChildBuilderDelegate(
                      (BuildContext context, int index) {
                        var data = widget.list[index];
                        return currentWidget(data);
                      },
                      childCount: widget.list.length,
                    ),
                  ))),
              Visibility(
                  visible: widget.socketType != SocketStateEnum.CONNECTED,
                  child: ChatRelinkWidget(widget.socketType, widget.pointText, context))
            ],
          ),
        ),
      ),
    );
  }

//发送当前已读消息到websocket】
  void _onSendReadStatus(List<int> lists) async {
    //获取当前用户所阅读的消息索引 数组
    var list = lists;
    List<String> dl = [];

    if (list.length > 0) {
      for (var i = 0; i < list.length; i++) {
        var s = list[i] ?? 0;
        if (s < widget.list!.length) {
          dynamic data = widget.list![s];
          if (data is ChatFields && data.type != null && data.messageId != null && data.type != 1) {
            if (data.isRead != 2) {
              data.isRead = 2;
              dl.add(data.messageId);
              print('*******messageId****${data.messageId}');
            }
          }
        }
      }
      print('*******dl****$dl');
      if (dl.length > 0) {
        //组装当前已阅读的消息数据 传回服务器
        UpdateReadType updateReadType = UpdateReadType.create()
          ..senderId = obtainValueByKey('id') == null ? "" : obtainValueByKey('id').toString()
          ..targetId = obtainValueByKey('servicerId') == null ? "" : obtainValueByKey('servicerId').toString()
          ..sessionId = obtainValueByKey('sessionId') == null ? "" : obtainValueByKey('sessionId').toString()
          ..msgs.addAll(dl);
        BaseMessage baseMessage = BaseMessage.create();
        baseMessage.action = 1006;
        baseMessage.data = updateReadType.writeToBuffer();
        MsgUtils.sendMessage(baseMessage.writeToBuffer());
      }
    }
  }

  _onRefresh() {
    if (Instance.isConnect == false) {
      _onEndRrefresh(widget.reverse ?? false);
    } else {
      widget.isScrollToBottom = false;
      onSendReques();
    }
  }

  _onEndRrefresh(bool reverse) {
    if (reverse == false) {
      widget.controller?.refreshCompleted();
    } else {
      widget.controller?.loadComplete();
    }
    setState(() {});
  }

  void onSendReques() async {
    HistoryMessage historyMessage = HistoryMessage.create();
    historyMessage.id = await obtainValueByKey('id').toString();
    historyMessage.platId = await obtainValueByKey('platId').toString();
    historyMessage.currentSessionId = Instance.currentSessionId ?? await obtainValueByKey('sessionId').toString();
    BaseMessage baseMessage = BaseMessage.create();
    baseMessage.action = 1008;
    baseMessage.data = historyMessage.writeToBuffer();

    MsgUtils.sendMessage(baseMessage.writeToBuffer());
  }

  Widget currentWidget(dynamic data) {
    if ((data is ChatFields)) {
      if (data.photo.length > 0 || data.text.length == 0 || data.text == null) {
        // var photo = data.photo[0];
        if (data.photo.length == 0 || data.photo == null || data.photo.first.startsWith('aac_')) {
          // return ChatVoicePage(data, viewService, playerInfo, servicerInfoFields, dispatch);
          return const SizedBox();
        } else {
          bool b = _isUpPicSuccess(data.photo[0], data.time.toString());
          return b
              ? PicMsgWidget<ChatFields, PlayerInfo, ServicerInfoFields>(data, widget.playerInfo!, widget.servicerInfoFields!,
                  loadingState: widget.loadingState)
              : Container(
                  child: GestureDetector(
                      onTap: () {
                        widget.keyBoardComponentPageState.currentState
                            ?.onUpPic(widget.images![data.time.toString()]!, widget.keyBoardComponentPageState.currentState!.widget.appId!);
                        onRemoveListFile(data.time);
                        onRemovePicFile(data.time.toString());
                      },
                      child: Container(
                          alignment: Alignment.centerRight,
                          padding: const EdgeInsets.only(top: 10, right: 50),
                          child: const Text('上传失败重新上传！', style: TextStyle(color: Colors.blue)))));
        }
      } else {
        return NormalTextWidget<ChatFields, PlayerInfo, ServicerInfoFields>(
            data, widget.playerInfo, widget.servicerInfoFields, widget.sendMsgStatus);
      }
    } else if (data is ServicerInfoFields) {
      return SystemContentWidget(data, context);
    } else if (data is ChatFaqModel) {
      return ChatFAQQuestionWidget(data);
    } else if (data is ChatAnwserModel) {
      return ChatMoreQuestionWidget(data);
    } else if (data is ChatResultModel) {
      return ChatAnwserWidget(data, widget.customerAvatar ?? "", widget.customername ?? "", widget.questBean!, widget.faqModel!);
    } else if (data is TimeDownBean) {
      return TimeDownText(data);
    } else {
      return SystemContentWidget(data, context);
    }
  }

  // 判断加载图片是否上传成功
  //
  bool _isUpPicSuccess(String url, String time) {
    //  如果为http开头则和这上传无关
    if (url.startsWith('http')) {
      return true;
    } else {
      // 不是http开始就是两种情况一种上传成功加载本地文件，一种上传失败
      return widget.images?[time] == null;
    }
  }

  //发送通知 取消定时器
  void oSendNoti() {
    NotificationCenter.post('cancel');
  }

  void onChangeIsScrollToBottom(bool isScrollToBottom) {
    widget.isScrollToBottom = isScrollToBottom;
    setState(() {});
  }

  void onShowChatFields(dynamic childFields) {
    if (childFields is List) {
      var list = [];
      for (var i = 0; i < childFields.length; i++) {
        var c = childFields[i];

        if (c.type == 1) {
          c.type = 2;
        } else {
          c.type = 1;
        }
        list.insert(0, c);
      }
      if (widget.reverse == true) {
        widget.list.addAll(list);
      } else {
        widget.list.insertAll(0, list);
      }
      if (list.length > 0) {
        widget.controller?.loadComplete();
      }
    } else {
      if (widget.reverse == false) {
        widget.list.add(childFields);
      } else {
        widget.list.insert(0, childFields);
      }
    }
    widget.list.length;
    setState(() {});
  }

  //点击已解决按钮 事件
  void onSolve(String string) async {
    oSendNoti();
    if (widget.isScrollToBottom == false) {
      onChangeIsScrollToBottom(true);
    }
    int nowTime = DateTime.now().millisecondsSinceEpoch;
    ChatFields chatFields = ChatFields.create()
      ..sessionId = await obtainValueByKey('sessionId').toString()
      ..text = string
      ..time = Int64(nowTime)
      ..username = await obtainValueByKey('username').toString()
      ..targetId = await obtainValueByKey('servicerId').toString()
      ..type = 1
      ..isRead = 2
      ..senderId = await obtainValueByKey('id').toString();
    onShowChatFields(chatFields);
    Future.delayed(Duration(seconds: 1), () {
      TimeDownBean bean = TimeDownBean();
      bean.time = 10;
      bean.type = 1;
      onShowChatFields(chatFields);
    });
  }

  //点击其他疑问按钮 事件
  void onOther(String string) async {
    oSendNoti();
    if (widget.isScrollToBottom == false) {
      onChangeIsScrollToBottom(true);
    }
    int nowTime = DateTime.now().millisecondsSinceEpoch;
    ChatFields chatFields = ChatFields.create()
      ..sessionId = await obtainValueByKey('sessionId').toString()
      ..text = string
      ..time = Int64(nowTime)
      ..username = await obtainValueByKey('username').toString()
      ..targetId = await obtainValueByKey('servicerId').toString()
      ..type = 1
      ..isRead = 2
      ..senderId = await obtainValueByKey('id').toString()
      ..messageId = nowTime.toString();
    onShowChatFields(chatFields);
    if (Instance.faqModel != null) {
      Future.delayed(Duration(seconds: 1), () {
        onShowChatFields(Instance.faqModel);
      });
    }
  }

  //改变listView是否倒置的状态
  onChangeReverse(bool reverse) {
    widget.reverse = reverse;
    setState(() {});
  }

  onHideFaqBtn() {}

  onRemoveListFile(dynamic time) {
    var list = widget.list;
    widget.list = list!.where((item) => item is ChatFields ? item.time != time : true).toList();
    setState(() {});
  }

  onRemovePicFile(String key) {
    widget.images?.remove(key);
    setState(() {});
  }

  onIsShowLoading(Map<String, bool> loadingState) {
    widget.loadingState?.addAll(loadingState);
    setState(() {});
  }

  onUpPicError(Map<String, File> file) {
    widget.images?.addAll(file);
    setState(() {});
  }

  uplateMsgStatus(Map map) {
    widget.sendMsgStatus.addAll(map);
    setState(() {});
  }

  void onShow(ChatFields childFields) {
    //消息过滤
    // if (widget.list.isNotEmpty) {
    //   var rlist = widget.list.where((element) =>
    //       (element is ChatFields &&
    //           element.messageId == childFields.messageId) ||
    //       (element is ChatAudio && element.messageId == childFields.messageId));
    //   if (rlist.toList().isNotEmpty) {
    //     print("消息重复，停止渲染");
    //     return;
    //   }
    // }
    if (widget.list.isNotEmpty) {
      dynamic data = widget.list!.first;
      if (childFields.time.toString() != null) {
        var oldTime = int.parse(data.time.toString());
        bool dif = DateUtil.timeDiffrence(oldTime);
        if (dif == true) {
          ServicerInfoFields servicerInfoFields = ServicerInfoFields.create();
          servicerInfoFields.declaration = showAllTime(DateTime.now().millisecondsSinceEpoch);
          onShowChatFields(servicerInfoFields);
        }
      }
    }
    if (childFields.messageId != null) {
      Map map = {childFields.messageId: "1"};
      uplateMsgStatus(map);

      const timeout = const Duration(seconds: 10);
      widget.sendTimer.add({
        "id": childFields.messageId,
        "timer": Timer(timeout, () {
          widget.sendMsgStatus[childFields.messageId] = "2";
          setState(() {});
        })
      });
    }
    onShowChatFields(childFields);
  }

  // 断线重连
  void reconnectAfterDisconnection() {
    widget.socketType = SocketStateEnum.CONNECTING;
    GlobalKey<ChatPageState> chatPageState = GlobalKey();
    chatPageState.currentState?.onConnect();
  }

  onSessionId(String sessionId) {
    widget.currentSessionId = sessionId;
    widget.isScrollToBottom = false;
    setState(() {});
  }

  void downloadHistoryData(List list) {
    // var msgs = list.length > 0 ? list[0].msgs : [];
    for (var i = 0; i < list.length; i++) {
      ChatFields chatFields = list[i];
      Future.delayed(Duration(milliseconds: 500), () {
        _downloadVoice(chatFields);
      });
    }
  }

  void _downloadVoice(dynamic data) async {
    ChatFields chatFields = data;
    if (chatFields.photo != null && chatFields.photo.length > 0) {
      if (chatFields.photo.first.startsWith('aac')) {
        String path = await Network().isExist(chatFields);
        if (path.length == 0) {
          download(chatFields);
        }
      }
    }
  }

  void download(ChatFields chatFields) async {
    List l = chatFields.photo.first.split('_');
    var filename = "";
    for (var i = 0; i < l.length - 1; i++) {
      if (i == 0) {
        filename = l[0];
      } else {
        filename = filename + '_' + l[i];
      }
    }
    var localPath = await fileMgr.getRootPath() + '/' + filename + '.aac';
    String uri = SocketManager().model!.baseUrl! + '/audio/' + filename;
    try {
      Network().download(uri, localPath, (data) => {}, (e) => {});
    } catch (e) {
      print(e.toString());
    }
  }

  //获取历史消息
  void onGetHistory(dynamic data) {
    MessageList messageList = data;
    Instance.currentSessionId = messageList.sessionId;
    print('=========messageList===========$messageList');
    if (messageList.msgs.length > 0) {
      widget.controller?.loadComplete();
      widget.controller?.refreshCompleted();
      onSessionId(messageList.sessionId);
    } else {
      widget.controller?.loadComplete();
      widget.controller?.refreshCompleted();
    }
    onShowChatFields(messageList.msgs);
    downloadHistoryData(messageList.msgs);
  }

  //当前没有客服在线 需要等待
  void onWait(dynamic data) {
    QueueInfo queueInfo = data;
    widget.waitCount = queueInfo.waitCount;
    ServicerInfoFields servicerInfoFields = ServicerInfoFields.create();
    servicerInfoFields.declaration = "当前系统客服繁忙，您已在排队等待中！当前排队人数${queueInfo.waitCount}人...";
    onShowChatFields(servicerInfoFields);
  }

// 用户因为被禁言或者其他原因拒绝连接服务器  协议号=====2000
  void onRefuse(dynamic data) {
    RejectPlayer rejectPlayer = data;
    FreezePlayer freezePlayer = FreezePlayer.create();
    String refuseTime = showAllTime(rejectPlayer.time);
    freezePlayer.type = 1;
    freezePlayer.reason = rejectPlayer.type == 1 ? "亲，您已被禁言\n禁言截止时间 $refuseTime" : "";
    widget.keyBoardComponentPageState.currentState?.onDontTalk(freezePlayer);
  }

  //已读消息处理
  onMsgRead() {
    for (var i = 0; i < widget.list.length; i++) {
      dynamic data = widget.list[i];
      if (data is ChatFields && data.isRead != null) {
        if (data.isRead != 2) {
          data.isRead = 2;
        }
      }
    }
    setState(() {});
  }

  onShowCurrentTime(dynamic data) {
    widget.timeServicerInfoFields = data;
    setState(() {});
  }
}
